from datetime import date
from typing import Literal
import xlwt
from decimal import Decimal
from xlwt import Workbook
from inventory.views.func.datatype import angle_steel_piece, special_all_angle_steel_list, \
    angle_weight_table, angle_steel_manual_table
from inventory.views.func.table_css import css1


# 行数自增器
class Row:
    def __init__(self, val):
        self.num = val

    @property
    def add(self):
        temp = self.num
        self.num += 1
        return temp

    @add.setter
    def add(self, val):
        self.num = val


# 打印角钢正品库销售表
def make_true_angle_steel_table(export_date: date, p_data: special_all_angle_steel_list, m_data: special_all_angle_steel_list):
    list_6_10 = ['6', '7', '8', '9', '10']
    list_6_12 = ['6', '7', '8', '9', '10', '11', '12']

    # 生成表格
    xl = xlwt.Workbook(encoding='utf-8')
    sheet1 = xl.add_sheet('Q235_1', cell_overwrite_ok=True)
    sheet2 = xl.add_sheet('Q235_2', cell_overwrite_ok=True)
    sheet3 = xl.add_sheet('Q235_3', cell_overwrite_ok=True)
    sheet4 = xl.add_sheet('Q235_4', cell_overwrite_ok=True)
    sheet5 = xl.add_sheet('Q355_1', cell_overwrite_ok=True)
    sheet6 = xl.add_sheet('Q355_2', cell_overwrite_ok=True)

    # 使用经典样式
    style, style_title = css1()

    # 设置单元格长度
    for k in [sheet1, sheet2, sheet3, sheet4, sheet5, sheet6]:
        k.col(0).width = 2430
        k.col(1).width = 2430
        k.col(2).width = 2430
        k.col(3).width = 2430
        k.col(4).width = 2430
        k.col(5).width = 2430
        k.col(6).width = 2430
        k.col(7).width = 2430
        k.col(8).width = 2430
        k.col(9).width = 2430
        k.col(10).width = 2430
        k.col(11).width = 2430

    # row是要写的那一行的
    def return_title(temp1, scale):

        temp1.write_merge(row.num, row.num + 1, 0, 9, '天津市兆博实业有限公司库存表', style_title)
        temp1.write(row.num + 2, 0, scale, style_title)

        temp1.write_merge(row.num + 2, row.num + 2, 8, 9, f'{export_date}', style_title)
        temp1.write_merge(row.num + 3, row.num + 5, 0, 0, '规格', style_title)
        temp1.write_merge(row.num + 3, row.num + 5, 1, 1, '支数/件', style_title)
        temp1.write_merge(row.num + 3, row.num + 5, 2, 2, '总件数', style_title)
        temp1.write_merge(row.num + 3, row.num + 4, 3, 7, '下差', style_title)
        temp1.write_merge(row.num + 3, row.num + 4, 8, 9, '备注', style_title)

        temp1.write(row.num + 5, 3, 'A', style_title)
        temp1.write(row.num + 5, 4, 'B', style_title)
        temp1.write(row.num + 5, 5, 'C', style_title)
        temp1.write(row.num + 5, 6, 'D', style_title)
        temp1.write(row.num + 5, 7, '国网', style_title)
        temp1.write(row.num + 5, 8, 'B', style_title)
        temp1.write(row.num + 5, 9, '网', style_title)

        row.add = row.num + 6

        return temp1

    # 件支数处理函数，如果件数和支数都为零，则不往表格里写入数据
    def data_change(temp_data: angle_steel_piece):
        if temp_data['whole_piece'] != 0 or temp_data['scatt_piece'] != 0:
            if temp_data['scatt_piece'] != 0:
                return f'{temp_data['whole_piece']} / {temp_data['scatt_piece']}'
            else:
                return temp_data['whole_piece']
        else:
            return ''


    # t_model：'40*3*' t_：[6, 7, 8, 9, 10]
    # data1 {'40*3*10': {'40310A': 20, '40310B': 30}, '40*3*11': {‘'40311A': 20, '40311B': 30}}
    # data2 {'40*3*10': [5, 286], '40*3*6': [1, 286]} 总件数，件支数
    def return_model(t_sheet, t_model, t_: list[str], is_m: bool = False):
        if is_m:
            manganese = 'M'
            t_data = m_data
        else:
            t_data = p_data
            manganese = ''
        # 查验该物料是否存在，不存在就直接返回
        if (t_model + t_[0]) not in t_data:
            return t_sheet
        row_number = len(t_)  # 确认该规格相同的物料有几个
        for i in range(row_number):
            # 规格
            if i == 0:
                t_sheet.write(row.num + i, 0, t_model + t_[i], style)
            else:
                t_sheet.write(row.num + i, 0, '*' + t_[i], style)
            # 支数/件
            t_sheet.write(row.num + i, 1, t_data[t_model + t_[i]]['set_piece'], style)

            temp_a = t_data[t_model + t_[i]]['material'][(manganese + t_model + t_[i] + 'A').replace("*", "")]
            t_sheet.write(row.num + i, 3, data_change(temp_a), style)

            temp_b = t_data[t_model + t_[i]]['material'][(manganese + t_model + t_[i] + 'B').replace("*", "")]
            t_sheet.write(row.num + i, 4, data_change(temp_b), style)

            temp_c = t_data[t_model + t_[i]]['material'][(manganese + t_model + t_[i] + 'C').replace("*", "")]
            t_sheet.write(row.num + i, 5, data_change(temp_c), style)

            temp_d = t_data[t_model + t_[i]]['material'][(manganese + t_model + t_[i] + 'D').replace("*", "")]
            t_sheet.write(row.num + i, 6, data_change(temp_d), style)

            temp_add = t_data[t_model + t_[i]]['material'][(manganese + t_model + t_[i] + '+').replace("*", "")]
            t_sheet.write(row.num + i, 7, data_change(temp_add), style)

            temp_total = temp_a['whole_piece'] + temp_b['whole_piece'] + temp_c['whole_piece'] + temp_d['whole_piece'] + \
                         temp_add['whole_piece']

            t_sheet.write(row.num + i, 2, '', style) if temp_total == 0 else t_sheet.write(row.num + i, 2, temp_total,
                                                                                           style)
            t_sheet.write(row.num + i, 8, '', style)
            t_sheet.write(row.num + i, 9, '', style)

        row.add = row.num + row_number + 1
        return t_sheet

    row = Row(0)

    sheet1 = return_title(sheet1, 'Q235')
    sheet1 = return_model(sheet1, '40*3*', list_6_10)
    sheet1 = return_model(sheet1, '40*4*', list_6_10)
    sheet1 = return_model(sheet1, '45*4*', list_6_10)
    sheet1 = return_model(sheet1, '45*5*', list_6_10)
    sheet1 = return_model(sheet1, '50*4*', list_6_12)
    sheet1 = return_model(sheet1, '50*5*', list_6_12)
    sheet1 = return_model(sheet1, '56*4*', list_6_12)
    return_model(sheet1, '56*5*', list_6_12)

    row = Row(0)

    sheet2 = return_title(sheet2, 'Q235')
    sheet2 = return_model(sheet2, '63*5*', list_6_12)
    sheet2 = return_model(sheet2, '63*6*', list_6_12)
    sheet2 = return_model(sheet2, '70*5*', list_6_12)
    sheet2 = return_model(sheet2, '70*6*', list_6_12)
    sheet2 = return_model(sheet2, '70*7*', list_6_12)
    sheet2 = return_model(sheet2, '75*5*', list_6_12)
    return_model(sheet2, '75*6*', list_6_12)

    row = Row(0)

    sheet3 = return_title(sheet3, 'Q235')
    sheet3 = return_model(sheet3, '75*7*', list_6_12)
    sheet3 = return_model(sheet3, '75*8*', list_6_12)
    sheet3 = return_model(sheet3, '80*6*', list_6_12)
    sheet3 = return_model(sheet3, '80*7*', list_6_12)
    sheet3 = return_model(sheet3, '80*8*', list_6_12)
    sheet3 = return_model(sheet3, '90*6*', list_6_12)
    return_model(sheet3, '90*7*', list_6_12)

    row = Row(0)

    sheet4 = return_title(sheet4, 'Q235')
    return_model(sheet4, '90*8*', list_6_12)

    row = Row(0)

    # 开始部分Q355部分
    sheet5 = return_title(sheet5, 'Q355')
    sheet5 = return_model(sheet5, '63*5*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '63*6*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '70*5*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '70*6*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '70*7*', ['7', '8', '9', '10'], is_m=True)
    sheet5 = return_model(sheet5, '75*5*', list_6_12, is_m=True)
    return_model(sheet5, '75*6*', list_6_12, is_m=True)

    row = Row(0)

    sheet6 = return_title(sheet6, 'Q355')
    sheet6 = return_model(sheet6, '80*6*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '80*7*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '80*8*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '90*6*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '90*7*', list_6_12, is_m=True)
    return_model(sheet6, '90*8*', list_6_12, is_m=True)

    # xl.save(r'/home/xph/Desktop/公司共享文件夹/132.xls')
    return xl


# 重量累加器
class Weight(object):
    def __init__(self):
        self.material_whole_piece: int = 0
        self.material_weight: Decimal = Decimal('0')
        self.material_theory_weight: Decimal = Decimal('0')

        self.page_whole_piece: int = 0
        self.page_weight: Decimal = Decimal('0')
        self.page_theory_weight: Decimal = Decimal('0')

        self.total_whole_piece: int = 0
        self.total_weight: Decimal = Decimal('0')
        self.total_theory_weight: Decimal = Decimal('0')

    # 清空本页的累计信息
    def clear_page(self):
        self.page_whole_piece: int = 0
        self.page_weight: Decimal = Decimal('0')
        self.page_theory_weight: Decimal = Decimal('0')

    # 清空材质的累计信息
    def clear_material(self):
        self.material_whole_piece: int = 0
        self.material_weight: Decimal = Decimal('0')
        self.material_theory_weight: Decimal = Decimal('0')

    # 逐条添加信息
    def add(self, whole_piece, weight, theory_weight):
        self.page_whole_piece += whole_piece
        self.page_weight += weight
        self.page_theory_weight += theory_weight

        self.material_whole_piece += whole_piece
        self.material_weight += weight
        self.material_theory_weight += theory_weight

        self.total_whole_piece += whole_piece
        self.total_weight += weight
        self.total_theory_weight += theory_weight


# 打印企管表，同一种规格显示总的件数，显示所有重量
def make_weight_angle_steel_table(export_date: date, p_data: angle_weight_table, m_data: angle_weight_table):
    list_6_10 = ['6', '7', '8', '9', '10']
    list_6_12 = ['6', '7', '8', '9', '10', '11', '12']

    # 生成表格
    xl = xlwt.Workbook(encoding='utf-8')
    sheet1 = xl.add_sheet('Q235_1', cell_overwrite_ok=True)
    sheet2 = xl.add_sheet('Q235_2', cell_overwrite_ok=True)
    sheet3 = xl.add_sheet('Q235_3', cell_overwrite_ok=True)
    sheet4 = xl.add_sheet('Q235_4', cell_overwrite_ok=True)
    sheet5 = xl.add_sheet('Q355_1', cell_overwrite_ok=True)
    sheet6 = xl.add_sheet('Q355_2', cell_overwrite_ok=True)

    # 使用经典样式
    style, style_title = css1()

    # 设置单元格长度
    for k in [sheet1, sheet2, sheet3, sheet4, sheet5, sheet6]:
        k.col(0).width = 2650
        k.col(1).width = 2650
        k.col(2).width = 2650
        k.col(3).width = 2650

    # row是要写的那一行的
    def return_title(temp1, scale):
        temp1.write_merge(row.num, row.num + 1, 0, 10, '兆博实业有限公司角钢库存盘点表', style_title)
        temp1.write(row.num + 2, 0, scale, style_title)
        temp1.write_merge(row.num + 2, row.num + 2, 9, 10, f'{export_date}', style_title)
        temp1.write_merge(row.num + 3, row.num + 4, 0, 0, '规格', style_title)
        temp1.write_merge(row.num + 3, row.num + 3, 1, 3, '正品库', style_title)
        temp1.write(row.num + 4, 1, '件数', style_title)
        temp1.write(row.num + 4, 2, '实际重量', style_title)
        temp1.write(row.num + 4, 3, '理论重量', style_title)
        row.add = row.num + 5
        return temp1

    # 数据行写入
    def return_model(t_sheet, t_model, t_: list[str], is_m: bool = False):
        if is_m:
            t_data = m_data
        else:
            t_data = p_data
        row_number = len(t_)  # 确认该规格相同的物料有几个
        for i in range(row_number):
            # 查验该物料是否存在，不存在就全部写入0
            data_exist = True
            if (t_model + t_[i]) not in t_data:
                data_exist = False
            # 规格
            if i == 0:
                t_sheet.write(row.num + i, 0, t_model + t_[i], style)
            else:
                t_sheet.write(row.num + i, 0, '*' + t_[i], style)
            # 这个大规格存在就写入实际数据，否则都写0就行
            if data_exist:
                a = t_data[t_model + t_[i]]['whole_piece']
                b = t_data[t_model + t_[i]]['weight']
                c = t_data[t_model + t_[i]]['theory_weight']
            else:
                a = b = c = 0
            # 正品库
            t_sheet.write(row.num + i, 1, a if a != 0 else '', style)
            t_sheet.write(row.num + i, 2, b if b != 0 else '', style)
            t_sheet.write(row.num + i, 3, c if c != 0 else '', style)
            # 进行累计
            weight_obj.add(a, b, c)

        row.add = row.num + row_number + 1
        return t_sheet

    # 本页总计行写入
    def page_total_summery(t_sheet):
        t_sheet.write(row.num, 0, '本页总计', style)
        t_sheet.write(row.num, 1, weight_obj.page_whole_piece, style)
        t_sheet.write(row.num, 2, weight_obj.page_weight, style)
        t_sheet.write(row.num, 3, weight_obj.page_theory_weight, style)
        row.add = row.num + 1
        return t_sheet

    # 物料总计行写入
    def material_total_summery(t_sheet, name: Literal['Q235总计', 'Q355总计']):
        t_sheet.write(row.num, 0, name, style)
        t_sheet.write(row.num, 1, weight_obj.material_whole_piece, style)
        t_sheet.write(row.num, 2, weight_obj.material_weight, style)
        t_sheet.write(row.num, 3, weight_obj.material_theory_weight, style)
        row.add = row.num + 1
        return t_sheet

    # 物料总计行写入
    def total_summery(t_sheet):
        t_sheet.write(row.num, 0, '全部总计', style)
        t_sheet.write(row.num, 1, weight_obj.total_whole_piece, style)
        t_sheet.write(row.num, 2, weight_obj.total_weight, style)
        t_sheet.write(row.num, 3, weight_obj.total_theory_weight, style)
        row.add = row.num + 1
        return t_sheet

    weight_obj = Weight()

    row = Row(0)

    sheet1 = return_title(sheet1, 'Q235')
    sheet1 = return_model(sheet1, '40*3*', list_6_10)
    sheet1 = return_model(sheet1, '40*4*', list_6_10)
    sheet1 = return_model(sheet1, '45*4*', list_6_10)
    sheet1 = return_model(sheet1, '45*5*', list_6_10)
    sheet1 = return_model(sheet1, '50*4*', list_6_12)
    sheet1 = return_model(sheet1, '50*5*', list_6_12)
    sheet1 = return_model(sheet1, '56*4*', list_6_12)
    sheet1 = return_model(sheet1, '56*5*', list_6_12)
    page_total_summery(sheet1)
    weight_obj.clear_page()

    row = Row(0)

    sheet2 = return_title(sheet2, 'Q235')
    sheet2 = return_model(sheet2, '63*5*', list_6_12)
    sheet2 = return_model(sheet2, '63*6*', list_6_12)
    sheet2 = return_model(sheet2, '70*5*', list_6_12)
    sheet2 = return_model(sheet2, '70*6*', list_6_12)
    sheet2 = return_model(sheet2, '70*7*', list_6_12)
    sheet2 = return_model(sheet2, '75*5*', list_6_12)
    sheet2 = return_model(sheet2, '75*6*', list_6_12)
    page_total_summery(sheet2)
    weight_obj.clear_page()

    row = Row(0)

    sheet3 = return_title(sheet3, 'Q235')
    sheet3 = return_model(sheet3, '75*7*', list_6_12)
    sheet3 = return_model(sheet3, '75*8*', list_6_12)
    sheet3 = return_model(sheet3, '80*6*', list_6_12)
    sheet3 = return_model(sheet3, '80*7*', list_6_12)
    sheet3 = return_model(sheet3, '80*8*', list_6_12)
    sheet3 = return_model(sheet3, '90*6*', list_6_12)
    sheet3 = return_model(sheet3, '90*7*', list_6_12)
    page_total_summery(sheet3)
    weight_obj.clear_page()

    row = Row(0)

    sheet4 = return_title(sheet4, 'Q235')
    sheet4 = return_model(sheet4, '90*8*', list_6_12)
    sheet4 = page_total_summery(sheet4)
    material_total_summery(sheet4, 'Q235总计')
    weight_obj.clear_page()
    weight_obj.clear_material()

    row = Row(0)

    # 开始部分Q355部分
    sheet5 = return_title(sheet5, 'Q355')
    sheet5 = return_model(sheet5, '63*5*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '63*6*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '70*5*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '70*6*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '70*7*', ['7', '8', '9', '10'], is_m=True)
    sheet5 = return_model(sheet5, '75*5*', list_6_12, is_m=True)
    sheet5 = return_model(sheet5, '75*6*', list_6_12, is_m=True)
    page_total_summery(sheet5)
    weight_obj.clear_page()

    row = Row(0)

    sheet6 = return_title(sheet6, 'Q355')
    sheet6 = return_model(sheet6, '80*6*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '80*7*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '80*8*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '90*6*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '90*7*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '90*8*', list_6_12, is_m=True)
    sheet6 = return_model(sheet6, '90*8*', list_6_12, is_m=True)
    sheet6 = page_total_summery(sheet6)
    sheet6 = material_total_summery(sheet6, 'Q355总计')
    total_summery(sheet6)

    return xl
    # xl.save(r'/home/xph/Desktop/公司共享文件夹/132.xls')


class RowNew:
    def __init__(self, val):
        self.num = val

    def add1(self):
        self.num += 1


# 生成角钢或带钢自动库存表格式的数据
def auto_store_table(in_data: list[angle_steel_manual_table], out_data: list[angle_steel_manual_table]) -> Workbook:
    # 生成表格
    xl = xlwt.Workbook(encoding='utf-8')
    sheet1 = xl.add_sheet('入库', cell_overwrite_ok=True)
    sheet2 = xl.add_sheet('出库', cell_overwrite_ok=True)

    # 使用经典样式
    style, style_title = css1()

    # 设置单元格长度
    for k in [sheet1, sheet2]:
        k.col(0).width = 4000
        k.col(1).width = 4000
        k.col(2).width = 4000

    # 写入数据
    row = RowNew(0)
    for i in in_data:
        sheet1.write(row.num, 0, i['material__code'], style)
        sheet1.write(row.num, 1, i['whole_piece'], style)
        sheet1.write(row.num, 2, i['weight'], style)
        row.add1()

    row = RowNew(0)
    for i in out_data:
        sheet2.write(row.num, 0, i['material__code'], style)
        sheet2.write(row.num, 1, i['whole_piece'], style)
        sheet2.write(row.num, 2, i['weight'], style)
        row.add1()

    return xl
